package la.bbs558.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import la.bbs558.aop.delay.DelayQueueEnum;
import la.bbs558.aop.delay.DelayQueueManager;
import la.bbs558.aop.delay.DelayTask;
import la.bbs558.aop.delay.handler.BbsClassActiveEndDelayHandler;
import la.bbs558.aop.delay.handler.BbsClassActiveStartDelayHandler;
import la.bbs558.dao.BbsClassActiveDao;
import la.bbs558.entity.BbsBoard;
import la.bbs558.entity.BbsClass;
import la.bbs558.entity.BbsClassActive;
import la.bbs558.entity.vo.BbsClassActiveVO;
import la.bbs558.exception.MsgException;
import la.bbs558.entity.params.BbsClassActivePage;
import la.bbs558.entity.params.BbsClassActiveParams;
import la.bbs558.service.BbsBoardService;
import la.bbs558.service.BbsClassActiveService;
import la.bbs558.service.BbsClassService;
import la.bbs558.util.Objs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 活动主题(BbsClassActive)表服务实现类
 *
 * @author makejava
 * @since 2024-01-19 11:12:00
 */
@Service("bbsClassActiveService")
@Slf4j
public class BbsClassActiveServiceImpl extends ServiceImpl<BbsClassActiveDao, BbsClassActive> implements BbsClassActiveService {

    @Resource
    private BbsClassActiveStartDelayHandler startDelayHandler;
    @Resource
    private BbsClassActiveEndDelayHandler endDelayHandler;
    @Resource
    private BbsClassService bbsClassService;
    @Resource
    private BbsBoardService bbsBoardService;

    @Override
    public void add(BbsClassActiveParams params) {
        List<Long> boardIds = params.getBoardIds();
        String activeName = params.getActiveName();
        String className = params.getClassName();
        Date startTime = params.getStartTime();
        BbsClassActive bbsClassActive = new BbsClassActive();
        bbsClassActive.setActiveName(activeName);
        bbsClassActive.setClassName(className);
        bbsClassActive.setStatus(-1);
        bbsClassActive.setStartTime(startTime);
        bbsClassActive.setEndTime(params.getEndTime());
        bbsClassActive.insert();
        for (Long boardId : boardIds) {
            BbsClass bbsClass = new BbsClass();
            bbsClass.setBoardId(boardId);
            bbsClass.setActivityId(bbsClassActive.getId());
            bbsClass.setClassName(className);
            bbsClass.setType(2);
            bbsClass.setStatus(bbsClassActive.getStatus());
            bbsClass.insert();
            this.addTask(bbsClass);
        }
    }

    @Override
    public void update(BbsClassActiveParams params) {
        Long activeId = params.getActiveId();
        Objs.valid(activeId, "活动id不能为空");
        String activeName = params.getActiveName();
        String className = params.getClassName();
        BbsClassActive classActive = new BbsClassActive();
        classActive.setId(activeId);
        classActive.setActiveName(activeName);
        classActive.setClassName(className);
        classActive.setStartTime(params.getStartTime());
        classActive.setEndTime(params.getEndTime());
        classActive.updateById();
        List<Long> boardIds = params.getBoardIds();
        List<Long> oldBoardIds = bbsClassService.lambdaQuery()
                .select(BbsClass::getBoardId)
                .eq(BbsClass::getActivityId, activeId).list()
                .stream().map(BbsClass::getBoardId).distinct().collect(Collectors.toList());
        for (Long boardId : boardIds) {
            // 新增的板块
            if (!oldBoardIds.contains(boardId)) {
                BbsClass bbsClass = new BbsClass();
                bbsClass.setBoardId(boardId);
                bbsClass.setActivityId(activeId);
                bbsClass.setClassName(className);
                bbsClass.setType(2);
                bbsClass.setStatus(-1);
                bbsClass.insert();
                this.addTask(bbsClass);
            } else {
                // 更新的板块
                bbsClassService.lambdaUpdate()
                        .set(BbsClass::getClassName, className)
                        .eq(BbsClass::getBoardId, boardId)
                        .eq(BbsClass::getActivityId, activeId)
                        .update();
                bbsClassService.lambdaQuery()
                        .eq(BbsClass::getBoardId, boardId)
                        .eq(BbsClass::getActivityId, activeId).oneOpt()
                        .ifPresent(this::addTask);
                oldBoardIds.remove(boardId);
            }
        }
        // 删除的板块
        for (Long oldBoardId : oldBoardIds) {
            bbsClassService.lambdaUpdate()
                    .set(BbsClass::getStatus, 0)
                    .set(BbsClass::getActivityId,null)
                    .eq(BbsClass::getActivityId, activeId)
                    .eq(BbsClass::getBoardId, oldBoardId)
                    .update();
        }
    }

    @Override
    public void addTask(BbsClass bbsClass) {
        BbsClassActive bbsClassActive = this.lambdaQuery().eq(BbsClassActive::getId, bbsClass.getActivityId()).one();
        if (bbsClassActive == null) {
            throw new MsgException("主题活动不存在");
        }
        DelayQueueManager startDelayQueue = DelayQueueManager.getDelayQueue(DelayQueueEnum.ACTIVE_START_DELAY_QUEUE);
        Date startTime = bbsClassActive.getStartTime();
        long startTimeout = startTime.getTime() - System.currentTimeMillis();
        boolean addStartTask = startDelayQueue.addTask(new DelayTask<>(bbsClass, startTimeout, TimeUnit.MILLISECONDS, 0, startDelayHandler));
        if (!addStartTask) {
            throw new MsgException("主题活动创建延时任务失败:002");
        }
        DelayQueueManager endDelayQueue = DelayQueueManager.getDelayQueue(DelayQueueEnum.ACTIVE_END_DELAY_QUEUE);
        Date endTime = bbsClassActive.getEndTime();
        long endTimeout = endTime.getTime() - System.currentTimeMillis();
        boolean addEndTask = endDelayQueue.addTask(new DelayTask<>(bbsClass, endTimeout, TimeUnit.MILLISECONDS, 0, endDelayHandler));
        if (!addEndTask) {
            throw new MsgException("主题活动创建延时任务失败:001");
        }
        log.info("主题活动创建延时任务成功:{}", bbsClass);
    }

    @Override
    public BbsClassActiveVO detail(Long activeId) {
        BbsClassActiveVO detail = getBaseMapper().detail(activeId);
        List<BbsBoard> boardList = bbsClassService.lambdaQuery()
                .select(BbsClass::getBoardId)
                .eq(BbsClass::getActivityId, activeId).list()
                .stream().map(BbsClass::getBoardId).distinct()
                .map(bbsBoardService::getById).collect(Collectors.toList());
        detail.setBbsBoardList(boardList);
        return detail;
    }

    @Override
    public void list(BbsClassActivePage page) {
        getBaseMapper().list(page);
        for (BbsClassActiveVO record : page.getRecords()) {
            List<BbsBoard> boardList = bbsClassService.lambdaQuery()
                    .select(BbsClass::getBoardId)
                    .eq(BbsClass::getActivityId, record.getId())
                    .list()
                    .stream()
                    .map(BbsClass::getBoardId)
                    .distinct()
                    .map(bbsBoardService::getById)
                    .collect(Collectors.toList());
            record.setBbsBoardList(boardList);
        }
    }

    @Override
    public void delete(Long activeId) {
        lambdaUpdate().eq(BbsClassActive::getId,activeId).remove();
        bbsClassService.lambdaUpdate()
                .set(BbsClass::getStatus, 0)
                .eq(BbsClass::getActivityId, activeId)
                .update();
    }
}

